<template>
  <div class="dashboard">
    <!-- 左侧问答区域 -->
    <div class="question-section">
      <el-card class="form-card">
        <template #header>
          <div class="card-header">
            <span>AI 智能问答</span>
          </div>
        </template>

        <el-form>
          <el-form-item>
            <el-input
              v-model="question"
              type="textarea"
              :rows="4"
              placeholder="请输入你的问题..."
              :maxlength="1000"
              show-word-limit
              @keyup.ctrl.enter="submitQuestion"
            />
            <div class="tips">
              <el-tag size="small" type="info">提示: 按Ctrl+Enter快速提交</el-tag>
            </div>
          </el-form-item>

          <el-form-item>
            <el-button 
              type="primary" 
              :loading="streaming"
              @click="submitQuestion"
            >
              <el-icon><ChatRound /></el-icon>
              获取AI解答
            </el-button>
          </el-form-item>
        </el-form>

        <div v-if="streaming || answer" class="answer-container">
          <div class="answer-header">
            <el-icon><Comment /></el-icon>
            <span>AI 回答</span>
          </div>
          <div class="editor-container">
            <div class="editor-wrapper">
              <Editor
                :defaultConfig="editorConfig"
                v-model="formattedAnswer"
                :mode="'default'"
                :style="{height: '100%'}"
                @onCreated="handleCreated"
              />
            </div>
          </div>
        </div>
      </el-card>
    </div>

    <!-- 右侧统计区域 -->
    <div class="stats-section">
      <el-card class="stats-card">
        <template #header>
          <div class="card-header">
            <span>学习统计</span>
          </div>
        </template>

        <el-row :gutter="20">
          <el-col :span="12">
            <div class="stat-item">
              <div class="stat-label">总问题数</div>
              <div class="stat-value">{{ stats.totalQuestions || 0 }}</div>
            </div>
          </el-col>
          <el-col :span="12">
            <div class="stat-item">
              <div class="stat-label">已学会</div>
              <div class="stat-value">{{ stats.learnedCount || 0 }}</div>
            </div>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="12">
            <div class="stat-item">
              <div class="stat-label">已收藏</div>
              <div class="stat-value">{{ stats.collectedCount || 0 }}</div>
            </div>
          </el-col>
          <el-col :span="12">
            <div class="stat-item">
              <div class="stat-label">平均难度</div>
              <div class="stat-value">
                {{ (stats.averageDifficulty || 0).toFixed(1) }}
              </div>
            </div>
          </el-col>
        </el-row>
      </el-card>

      <!-- 最近问题列表 -->
      <el-card class="recent-questions-card">
        <template #header>
          <div class="card-header">
            <span>最近问题</span>
          </div>
        </template>

        <el-scrollbar height="300px">
          <div
            v-for="question in recentQuestions"
            :key="question.id"
            class="question-item"
            @click="goToQuestion(question.id)"
          >
            <div class="question-text">{{ question.question }}</div>
            <div class="question-meta">
              <div class="meta-left">
                <el-rate
                  v-model="question.difficulty"
                  :colors="difficultyColors"
                  :max="5"
                  disabled
                  class="difficulty-rate"
                />
                <el-tag 
                  size="small" 
                  :type="Boolean(question.isLearned) ? 'success' : ''"
                  class="status-tag"
                >
                  {{ Boolean(question.isLearned) ? "已学习" : "学习中" }}
                </el-tag>
                <el-tag 
                  size="small" 
                  :type="Boolean(question.isCollected) ? 'warning' : ''"
                  class="status-tag"
                >
                  {{ Boolean(question.isCollected) ? "已收藏" : "收藏" }}
                </el-tag>
              </div>
              <el-tooltip 
                :content="formatDetailTime(question.createTime)"
                placement="top"
              >
                <span class="question-time">{{ formatTime(question.createTime) }}</span>
              </el-tooltip>
            </div>
          </div>
        </el-scrollbar>
      </el-card>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, shallowRef, nextTick } from 'vue'
import { ChatRound, Comment } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
import '@wangeditor/editor/dist/css/style.css'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import hljs from 'highlight.js'
import 'highlight.js/styles/atom-one-dark.css'
import axios from 'axios'
import { formatRelativeTime, formatDetailTime } from '@/utils/timeFormat'

const router = useRouter()
const question = ref('')
const answer = ref('')
const streaming = ref(false)
const stats = ref({})
const recentQuestions = ref([])
const editor = shallowRef()

// 编辑器配置
const editorConfig = {
  readOnly: true,
  autoFocus: false,
  scroll: false,
  MENU_CONF: {
    codeBlock: {
      highlightjs: hljs,
      languageList: [
        { text: 'Java', value: 'java' },
        { text: 'JavaScript', value: 'javascript' },
        { text: 'HTML', value: 'html' },
        { text: 'CSS', value: 'css' },
        { text: 'Python', value: 'python' },
        { text: 'SQL', value: 'sql' },
        { text: 'Bash', value: 'bash' },
        { text: 'Plain Text', value: 'plaintext' }
      ]
    }
  }
}

// 处理编辑器创建完成
const handleCreated = (e) => {
  editor.value = e
}

const formatAnswer = (answer) => {
  if (!answer) return ''
  
  // 处理代码块
  let formattedContent = answer.replace(/```(\w*)([\s\S]*?)```/g, (match, language, code) => {
    language = language.trim() || 'plaintext'
    code = code.trim()
    return `<pre><code class="language-${language}">${code}</code></pre>`
  })

  // 处理标题
  formattedContent = formattedContent
    .replace(/^#### (.*$)/gm, '<h4>$1</h4>')
    .replace(/^### (.*$)/gm, '<h3>$1</h3>')
    .replace(/^## (.*$)/gm, '<h2>$1</h2>')
    .replace(/^# (.*$)/gm, '<h1>$1</h1>')

  // 处理水平线
  formattedContent = formattedContent.replace(/^---$/gm, '<hr>')

  // 处理列表
  let inList = false
  formattedContent = formattedContent.split('\n').map(line => {
    const listMatch = line.match(/^- (.+)$/)
    if (listMatch) {
      if (!inList) {
        inList = true
        return `<ul><li>${listMatch[1]}</li>`
      }
      return `<li>${listMatch[1]}</li>`
    } else if (inList && line.trim()) {
      inList = false
      return `</ul>${line}`
    } else if (inList && !line.trim()) {
      inList = false
      return '</ul>'
    }
    return line
  }).join('\n')

  // 处理其他 Markdown 语法
  formattedContent = formattedContent
    .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
    .replace(/\*(.*?)\*/g, '<em>$1</em>')
    .replace(/`([^`]+)`/g, '<code>$1</code>')
    .replace(/\[(.*?)\]\((.*?)\)/g, '<a href="$2" target="_blank">$1</a>')

  // 处理普通文本段落
  return formattedContent.split('\n').map(line => {
    if (line.trim() && !line.includes('<h') && !line.includes('<pre>') && !line.includes('<hr>') && !line.includes('<ul>') && !line.includes('<li>') && !line.includes('</ul>')) {
      return `<p>${line}</p>`
    }
    return line
  }).join('\n')
}

const formattedAnswer = computed({
  get: () => formatAnswer(answer.value),
  set: (val) => {
    // 编辑器可能会尝试修改内容，但我们不允许修改
    // 这里不做任何处理，保持只读
  }
})

const submitQuestion = async () => {
  if (!question.value.trim()) return

  streaming.value = true
  answer.value = ''
  const currentQuestion = question.value

  if (window._currentEventSource) {
    window._currentEventSource.close()
    window._currentEventSource = null
  }

  const eventSource = new EventSource(
    `/api/questions/stream?question=${encodeURIComponent(currentQuestion)}`
  )
  window._currentEventSource = eventSource

  const timeout = setTimeout(() => {
    if (eventSource && eventSource.readyState !== EventSource.CLOSED) {
      cleanup()
      ElMessage.warning('回答超时，请重试')
    }
  }, 300000)

  const cleanup = () => {
    clearTimeout(timeout)
    if (eventSource) {
      eventSource.close()
      window._currentEventSource = null
    }
    streaming.value = false
  }

  eventSource.addEventListener('message', (event) => {
    try {
      const data = JSON.parse(event.data)
      
      if (typeof data === 'string') {
        answer.value += data
      } else if (Array.isArray(data)) {
        const typeData = data[0]
        if (typeData.data === 'event:error\ndata:') {
          handleError()
          return
        }
        if (typeData.data === 'event:complete\ndata:') {
          handleComplete()
          return
        }
        if (data[1] && data[1].data) {
          answer.value += data[1].data
        }
      }

      // 自动滚动到底部
      nextTick(() => {
        const editorWrapper = document.querySelector('.editor-wrapper')
        if (editorWrapper) {
          editorWrapper.scrollTop = editorWrapper.scrollHeight
        }
      })
    } catch (error) {
      console.error('Error parsing stream data:', error)
      answer.value += event.data
    }
  })

  const handleComplete = async () => {
    try {
      console.log('ai回答完成')
      cleanup()

      const response = await axios.post('/api/questions', {
        question: currentQuestion,
        answer: answer.value,
      })

      if (response.data) {
        question.value = ''
        await Promise.all([fetchStats(), fetchRecentQuestions()])
        ElMessage.success('问题已保存')
      }
    } catch (error) {
      console.error('Failed to save question:', error)
      ElMessage.error('保存问题失败')
    }
  }

  const handleError = async () => {
    try {
      console.log('ai回答报错')
      cleanup()
      ElMessage.error('AI服务出错，请重试')
    } catch (error) {
      console.error('Error handling error event:', error)
      ElMessage.error('处理错误时发生异常')
    }
  }

  eventSource.addEventListener('error', (event) => {
    if (event.data) {
      ElMessage.error(event.data)
    }
    cleanup()
  })

  eventSource.addEventListener('open', () => {
    console.log('Connection established')
  })
}

const formatTime = (time) => {
  return formatRelativeTime(time)
}

const fetchStats = async () => {
  try {
    const response = await axios.get('/api/questions/statistics')
    stats.value = response.data
  } catch (error) {
    console.error('Failed to fetch stats:', error)
  }
}

const fetchRecentQuestions = async () => {
  try {
    const response = await axios.get('/api/questions')
    recentQuestions.value = response.data.slice(0, 5)
  } catch (error) {
    console.error('Failed to fetch recent questions:', error)
  }
}

const goToQuestion = (id) => {
  router.push({
    path: '/history',
    query: { scrollTo: id }
  })
}

const difficultyColors = ['#67C23A', '#E6A23C', '#F56C6C']

const toggleLearned = async (question) => {
  try {
    await axios.post(`/api/questions/${question.id}/learned`)
    await fetchRecentQuestions()
    ElMessage.success(question.isLearned ? '已取消学会标记' : '已标记为学会')
  } catch (error) {
    ElMessage.error('操作失败')
  }
}

const toggleCollect = async (question) => {
  try {
    await axios.post(`/api/questions/${question.id}/collect`, {
      isCollected: !question.isCollected
    })
    await fetchRecentQuestions()
    ElMessage.success(question.isCollected ? '已取消收藏' : '已收藏')
  } catch (error) {
    ElMessage.error('操作失败')
  }
}

onMounted(async () => {
  await Promise.all([fetchStats(), fetchRecentQuestions()])
})

onUnmounted(() => {
  if (window._currentEventSource) {
    window._currentEventSource.close()
    window._currentEventSource = null
  }
  if (editor.value) {
    editor.value.destroy()
  }
})
</script>

<style scoped>
.dashboard {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 20px;
  max-width: 1400px;
  margin: 20px auto;
  padding: 0 20px;
}

.question-section {
  max-width: 900px;
}

.form-card {
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.card-header {
  display: flex;
  align-items: center;
  font-size: 18px;
  font-weight: bold;
  color: #409eff;
}

.tips {
  margin-top: 8px;
  display: flex;
  justify-content: flex-end;
}

.answer-container {
  margin-top: 20px;
  background-color: #ffffff;
  border-radius: 4px;
}

.answer-header {
  display: flex;
  align-items: center;
  padding: 12px 15px;
  border-bottom: 1px solid #ebeef5;
}

.answer-header .el-icon {
  margin-right: 8px;
  font-size: 16px;
  color: #409eff;
}

.answer-header span {
  font-size: 14px;
  font-weight: 500;
  color: #303133;
}

.editor-container {
  border: none;
  position: relative;
}

.editor-wrapper {
  height: 360px;
  overflow-y: auto;
  padding: 16px;
  background-color: #ffffff;
  border-radius: 4px;
}

.editor-wrapper::-webkit-scrollbar {
  width: 4px;
}

.editor-wrapper::-webkit-scrollbar-thumb {
  background-color: #e4e7ed;
  border-radius: 2px;
}

:deep(.w-e-text-container) {
  background: transparent !important;
  border: none !important;
  height: auto !important;
  min-height: auto !important;
  overflow: visible !important;
}

:deep(.w-e-text-container p) {
  margin: 8px 0;
  line-height: 1.6;
}

:deep(.w-e-text-container pre) {
  background-color: #282c34;
  border-radius: 6px;
  margin: 16px 0;
}

:deep(.w-e-text-container pre code) {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
  font-size: 14px;
  line-height: 1.5;
}

:deep(.w-e-text-container blockquote) {
  border-left: 4px solid #dfe2e5;
  padding: 0 1em;
  color: #6a737d;
  margin: 1em 0;
}

:deep(.w-e-text-container h4) {
  font-size: 1.1em;
  margin: 1em 0 0.6em;
  color: #2c3e50;
}

:deep(.w-e-text-container hr) {
  border: none;
  border-top: 1px solid #e4e7ed;
  margin: 1.2em 0;
}

:deep(.w-e-text-container code) {
  background-color: #f3f4f5;
  border-radius: 3px;
  padding: 0.2em 0.4em;
  font-size: 0.9em;
  color: #476582;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
}

:deep(.w-e-text-container ul) {
  list-style-type: disc;
  padding-left: 1.5em;
  margin: 0.8em 0;
}

:deep(.w-e-text-container li) {
  line-height: 1.6;
  margin: 0.5em 0;
  color: #2c3e50;
  position: relative;
}

:deep(.w-e-text-container li::marker) {
  color: #409eff;
}

:deep(.w-e-text-container li p) {
  margin: 0;
}

:deep(.w-e-text-container li code) {
  margin: 0 0.2em;
}

:deep(.w-e-toolbar) {
  display: none !important;
}

.stats-section {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.stats-card,
.recent-questions-card {
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.stat-item {
  text-align: center;
  padding: 15px;
  background-color: #f8f9fa;
  border-radius: 8px;
  margin-bottom: 15px;
}

.stat-label {
  color: #606266;
  font-size: 14px;
  margin-bottom: 8px;
}

.stat-value {
  color: #409eff;
  font-size: 24px;
  font-weight: bold;
}

.question-item {
  padding: 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.3s ease;
  border-bottom: 1px solid #ebeef5;
}

.question-item:hover {
  background-color: #f5f7fa;
  transform: translateY(-2px);
}

.question-item:last-child {
  border-bottom: none;
}

.question-text {
  font-size: 14px;
  color: #303133;
  margin-bottom: 8px;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.question-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: #909399;
  margin-top: 8px;
}

.meta-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.difficulty-rate {
  transform: scale(0.8);
  transform-origin: left;
}

.status-tag {
  transform: scale(0.8);
  transform-origin: left;
}

.question-time {
  color: #909399;
  font-size: 13px;
  cursor: default;
}
</style> 